/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Dao;

import static Dao.CatalogoDAO.rs;
import Dto.CatalogoDTO;
import Dto.ClienteDTO;
import Modelo.Conexion;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


/**
 *
 * @author -ADMIN-
 */
public class ClienteDAO {
    
    public static Connection con = Conexion.getInstance();
    public static PreparedStatement pstm;
    public static CallableStatement cstm;
    public static ResultSet rs;
    
    public static final String SQL_INSERT="INSERT INTO usuarios(Identificacion, nombre1,apellido1,apellido2, direccion, fecha_nac, cel, correo, clave) "
            + "values(?,?,?,?,?,?,?,?,?)";    
    public static final String SQL_DELETE= "DELETE FROM usuarios WHERE Identificacion=?";
    public static final String SQL_UPDATE= "UPDATE usuarios SET nombre1=?, apellido1=?, cel= ?,  direccion = ? WHERE Identificacion = ?";
    public static final String SQL_READ= "SELECT * FROM usuarios WHERE Identificacion = ?";
    public static final String SQL_READALL= "SELECT Identificacion, nombre1, nombre2, apellido1,apellido2, direccion, fecha_nac, cel, correo FROM usuarios where 1=1";
    
    
    public static synchronized int registroCliente(ClienteDTO c) {
        String call = "{CALL sp_RegistrarseCliente(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}";
        int rpta = 0;
        try {
            con.setAutoCommit(false);
            cstm = con.prepareCall(call);
            cstm.setInt(1, c.getId());
            cstm.setString(2, c.getNombre());
            cstm.setString(3, c.getApellido1());
            cstm.setString(4, c.getApellido2());
            cstm.setString(5,  c.getNacido());
            cstm.setString(6, c.getDireccion());
            cstm.setLong(7, c.getCel());
            cstm.setString(8, c.getCorreo());
            cstm.setString(9, c.getClave());
            cstm.registerOutParameter(10, java.sql.Types.INTEGER);
            cstm.executeUpdate();
            
            rpta = cstm.getInt(10);
            
            // rpta retorn 1: exitoso, 2: error iduser ya existe, 3: correo ya existe
            if(rpta == 1){
                con.commit();
            }else{
                Conexion.deshacerCambios(con);
            }
        } catch (SQLException e) {
            throw new RuntimeException("error al crear cliente: "+e.getStackTrace()+" "+e.getMessage());
        }finally{
            Conexion.cerrarCall(cstm);
        }
        
        return rpta;
    }

    public static synchronized ClienteDTO validarInicioSesion(String correo, String pass){
        int rpta = 0;
        ClienteDTO cdto = null;
        String callv = "{CALL sp_validarInicioSesion(?, ?, ?)}";
         
         try {
            cstm = con.prepareCall(callv);
            cstm.setString(1, correo);
            cstm.setString(2, pass);
            cstm.registerOutParameter(3, java.sql.Types.INTEGER);
            rs = cstm.executeQuery();
            
            int result = cstm.getInt(3);
            
            if( result != 0){
                 while (rs.next()) {
                    cdto = new ClienteDTO(result, rs.getString("nombre"), rs.getString("apellido1"), rs.getString("apellido2"), rs.getString("fecha_nacimiento"),rs.getString("direccion") , rs.getLong("celular"), correo, pass);
                }
            }else{
                cdto = null;
            }
            
         } catch (SQLException ex) {
             throw new RuntimeException("error al validar inicio de sesion"+ex.getSQLState()+" "+ex.getMessage());
         }
        
        return cdto;
    }
    
    public static synchronized String consultarRolUsuario(int id){
        String salida;
             String consulta = "{CALL sp_consultarRolUsuario(?, ?)}";
        try{
            cstm = con.prepareCall(consulta);
            cstm.setInt(1, id);
            cstm.registerOutParameter(2, java.sql.Types.VARCHAR);
            cstm.execute();
            salida = cstm.getString(2);
            
        }catch(SQLException sqle){
            throw new RuntimeException("error : "+sqle.getSQLState()+" = "+sqle.getMessage());
        }
        return salida;
    }
    
    public static synchronized boolean updateDatosCliente(ClienteDTO u) {
        boolean rpta = false;
        int salida = 0;
        String call = "{CALL  sp_actualizarDatosCliente(?, ?, ?, ?, ?, ?, ?, ?)}";
        try {
            con.setAutoCommit(false);
            cstm = con.prepareCall(call);
            cstm.setInt(1, u.getId());
            cstm.setString(2, u.getNombre());
            cstm.setString(3, u.getApellido1());
            cstm.setString(4, u.getApellido2());
            cstm.setString(5, u.getNacido());
                // cstm.setDate(5, (Date) u.getFecha_nac());
            cstm.setString(6, u.getDireccion());
            cstm.setLong(7, u.getCel());
            cstm.setString(8, u.getCorreo());
             salida =  cstm.executeUpdate();
            
            if(salida == 1){
                rpta = true;
                con.commit();
            }else{
                Conexion.deshacerCambios(con);
            }
        } catch (SQLException e) {
            throw new RuntimeException("error al actualizar informacion de perfil: "+e.getLocalizedMessage()+ " "+e);
        }
        return rpta;
    }
    
     public static synchronized int cambioClave(int id, String claveActual, String claveNueva) {
        String call = "{CALL sp_cambioClaveUsuario(?, ?, ?, ?)}";
        int rpta = 0;
        try {
            con.setAutoCommit(false);
            cstm = con.prepareCall(call);
            cstm.setInt(1, id);
            cstm.setString(2, claveActual);
            cstm.setString(3, claveNueva);
            cstm.registerOutParameter(4, java.sql.Types.INTEGER);
            cstm.execute();
            rpta = cstm.getInt(4);
            /* si la salida es 0 no es correcta la clave actual, sino si salida = 1 proceso exitoso*/
            if(rpta == 1){
                con.commit();
            }else{
                Conexion.deshacerCambios(con);
            }
        }catch (SQLException e){
            throw new RuntimeException("error al intentar cambiar la contraseña : "+e);
        }
        
         return rpta;
     }
    
    public static synchronized int reestablecerClave(String email, String clave) {
        int salida = 0;
        String call = "{call sp_olvidoContraseña(?, ?, ?)}";
        
        try{
            con.setAutoCommit(false);
            cstm = con.prepareCall(call);
            cstm.setString(1, email);
            cstm.setString(2, clave);
            cstm.registerOutParameter(3, java.sql.Types.INTEGER);
            cstm.execute();
            
            int result = cstm.getInt(3);
            // si resultado es 1 fue exitoso;
            
            if(result == 1){
                con.commit();
                salida = 1;
            }else{
                Conexion.deshacerCambios(con);
            }
            
        }catch(SQLException ex){
            throw new RuntimeException("error al ejecutar procedimiento almacenado de restablecer Clave: "+ex);
        }
        
        return salida;
    }
    
    public static synchronized boolean deleteCliente(int id) {
        boolean result = false;
        try{
            pstm = con.prepareStatement(SQL_DELETE);
            pstm.setInt(1, id);
            
            if(pstm.executeUpdate() > 0){
                result = true;
            }
        }catch(SQLException sqe){
            throw new RuntimeException(" error: "+sqe.getMessage());
        }
        
        return result;
    }

    
    public static synchronized ClienteDTO readUsuarioById(int id) {
        ClienteDTO cl = null;
         String call = "{call sp_consultarClienteById(?)}";  
        try{
           cstm = con.prepareCall(call);
           cstm.setInt(1, id);
           rs = cstm.executeQuery();
           
           String nombre= rs.getString("nombre");
           String apellido1 = rs.getString("apellido1");
           String apellido2= rs.getString("apellido2");
           String fecha = rs.getString("fecha_nacimiento");
           String direccion= rs.getString("direccion");
           long celular  =Long.parseLong( rs.getString("celular"));
           String correo= rs.getString("correo");
           
           if(rs != null){
                while(rs.next()){
                    cl = new ClienteDTO(id, nombre, apellido1, apellido2, fecha, direccion, celular, correo);
                }
           }
        }catch(SQLException sq){
               throw new RuntimeException("erro: "+sq.getSQLState()+" = "+sq.getMessage());
        }
        
        return cl;
    }

    
    public static synchronized List<ClienteDTO> readAll() {
        ArrayList<ClienteDTO> lista = new ArrayList<>();
            try{
                pstm = con.prepareStatement(SQL_READALL);
                rs = pstm.executeQuery();
                int id = rs.getInt("Identificacion");
                String nombre1 = rs.getString("nombre1");
                String nombre2 = rs.getString("nombre2");
                String apellido1 = rs.getString("apellido1");
                String apellido2 = rs.getString("apellido2");
                String direccion = rs.getString("direccion");
                String nace = rs.getString("fecha_nac");
                long celular = rs.getLong("cel");
                String correo = rs.getString("correo");
                while(rs.next()){
                    lista.add(new ClienteDTO(id, nombre2, apellido1, apellido2, nace, direccion, celular, correo));
                }
            }catch(SQLException sqe){
                throw new RuntimeException("error: "+sqe.getSQLState()+" = "+sqe.getMessage());
            }
        return lista;
    }

    public static synchronized ClienteDTO buscarUsuario(String buscar) {
           ClienteDTO cliente = null;
           String usu = "select idUsuarios, nombre, apellido1, apellido2, fecha_nacimiento, direccion, celular, correo from usuarios where nombre = ?";
           try{
           pstm = con.prepareStatement(usu);
           pstm.setString(1, buscar);
           rs = pstm.executeQuery();
           int id = rs.getInt("Identificacion");
           String nombre= rs.getString("nombre");
           String apellido1 = rs.getString("apellido1");
           String apellido2= rs.getString("apellido2");
           String fecha = rs.getString("fecha_nacimiento");
           String direccion= rs.getString("direccion");
           long celular  =Long.parseLong( rs.getString("celular"));
           String correo= rs.getString("correo");
           if(rs != null){
                while(rs.next()){
                    cliente = new ClienteDTO(id, nombre, apellido1, apellido2, fecha, direccion, celular, correo);
                }   
           }
           }catch(SQLException sq){
               throw new RuntimeException("erro: "+sq.getSQLState()+" = "+sq.getMessage());
           }
           
           return cliente;    
    }

    
    
}
